﻿using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace Xejen.Editor
{
    /// <summary>
    /// 表示显示数据的窗体
    /// </summary>
    /// <creator>marc</creator>
    public partial class DataVisualizeForm : FormBase
    {
        /// <summary>
        /// 采用哪种语言的语法
        /// </summary>
        private readonly string _language;

        private readonly WebView2 _dataTextBox;

        /// <summary>
        /// 数据
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Data { get; set; }

        /// <summary>
        /// 窗体标题
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Title { get; set; }

        /// <inheritdoc cref="DataVisualizeForm"/>
        /// <param name="data">待可视化的数据</param>
        /// <param name="title">窗体标题</param>
        /// <param name="language">采用哪种语言的高亮语法（区分大小写）。<br/>若传空则自动识别，目前支持自动识别：json 和 xml</param>
        /// <param name="readWriteType"><inheritdoc cref="ReadWriteType" path="/summary"/></param>
        public DataVisualizeForm(string data, string title = null, string language = null, ReadWriteType readWriteType = ReadWriteType.Read)
        {
            Data = data;
            Title = title;
            _language = language;

            InitializeComponent();

            _dataTextBox = new WebView2
            {
                Dock = DockStyle.Fill
            };
            ContainerPanel.Controls.Add(_dataTextBox);

            if (readWriteType == ReadWriteType.Write)
            {
                SavePanel.Visible = true;
            }
        }

        /// <inheritdoc/>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!string.IsNullOrEmpty(Title))
            {
                this.Text = Title;
            }

            LoadEditor();
        }

        private void LoadEditor()
        {
            string content = Data;
            string language = "plaintext";

            if (!string.IsNullOrEmpty(Data))
            {
                if (Data.IsJson())
                {
                    content = Data.FormatJson();
                    language = "json";
                }
                else if (Data.IsXml())
                {
                    content = Data.FormatXml();
                    language = "xml";
                }
            }

            string htmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "monaco-editor.html");

            _dataTextBox.CoreWebView2InitializationCompleted += (sender, args) =>
            {
                if (!args.IsSuccess)
                {
                    MessageBox.Show("WebView2 initialization failed.");
                    return;
                }

                _dataTextBox.CoreWebView2.WebMessageReceived += (sender2, args2) =>
                {
                    if (args2.TryGetWebMessageAsString() == "initialized")
                    {
                        _dataTextBox.CoreWebView2.ExecuteScriptAsync($"setEditorContent({JsonConvert.SerializeObject(content)}, '{_language ?? language}');");
                        SaveButton.Enabled = true;
                    }
                };

                _dataTextBox.CoreWebView2.NavigateToString(File.ReadAllText(htmlPath));
            };

            _dataTextBox.Source = new Uri(htmlPath);
        }

        /// <summary>
        /// 预加载
        /// </summary>
        public void Preload()
        {
            LoadEditor();
        }

        /// <summary>
        /// 设置界面大小
        /// </summary>
        /// <param name="size">界面大小值设定</param>
        public void SetClientSize(Size size)
        {
            this.ClientSize = size;
        }

        /// <summary>
        /// 设置保存按钮的文字
        /// </summary>
        /// <param name="text">文字</param>
        public void SetSaveButtonText(string text)
        {
            SaveButton.Text = text;
        }

        /// <summary>
        /// 获取文本数据内容
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetDataAsync()
        {
            return JsonConvert.DeserializeObject(await _dataTextBox.CoreWebView2.ExecuteScriptAsync("getEditorContent();")).ToString();
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
        }
    }

    /// <summary>
    /// 表示读写类型
    /// </summary>
    public enum ReadWriteType : short
    {
        /// <summary>
        /// 读，这是默认的
        /// </summary>
        Read = 0,
        /// <summary>
        /// 写
        /// </summary>
        Write = 1,
    }
}
